const UniPush = require('uni-push')
const {
	Service
} = require('uni-cloud-router')
const dbUtil = require('db-util')
const MSG_START = 'start' //开始剧本
const MSG_SWITCH_ROLES = 'switchRoles' //选择（切换）角色
const MSG_SWITCH_PHASE = 'switchPhase' //DM切换阶段
const MSG_SEND_CLUE = 'sendClue' //DM发送线索（玩家公开线索，玩家搜证线索）
const MSG_CANCEL_CLUE = 'cancelClue' //DM撤回线索
const MSG_SEND_ITEM = 'sendItem' //DM发送物品（道具，内容，结局）
const MSG_CANCEL_ITEM = 'cancelItem' //DM发送物品（道具，内容，结局）
const MSG_SEND_QUESTION = 'sendQuestion' //DM发送投凶问题给玩家
const MSG_SEND_ANWSER = 'sendAnwser' //发送玩家的回答给DM
const MSG_CALL_DM = 'callDM' //玩家呼叫dm
const MSG_CANCEL_CALL = 'cancelCall' //玩家取消呼叫
const MSG_CALL_OK = 'callOK' //DM确认玩家呼叫
const MSG_QUIT_ROOM = 'quitRoom' //玩家退出房间
const MSG_DEAL_APPLY = 'dealApply' //玩家向DM发送交易申请
const MSG_SEND_MAP = 'sendMap' //DM发送搜证地图给玩家
const MSG_SEND_SKILL = 'sendSkill' //DM发送技能给玩家
const MSG_DEAL_CLUE = 'dealClue' //向玩家发出交易线索的请求
module.exports = class GamingService extends Service {
	//消息推送
	async pushMessage({
		clientId,
		type,
		data
	}) {
		let res = await UniPush("toSingle", {
			"title": "离线时显示的标题",
			"content": "离线时显示的副标题",
			"payload": JSON.stringify({
				"title": "在线时显示的标题",
				"content": "在线时显示的副标题",
				"data": {
					type,
					data
				}
			}),
			"clientid": clientId
		})
		console.log('push complete', res)
	}

	//DM点击开始剧本后创建房间
	async start({
		clientIds,
		scriptId,
		dmClientid
	}) {
		//判断剧本是否存在
		let script = await dbUtil.getById({
			collection: 't3ds-script',
			id: scriptId
		})
		if (!script) {
			throw new Error("该剧本不存在")
		}
		//判断接入设备是否可用
		let clientList = []
		for (let i = 0; i < clientIds.length; i++) {
			let client = await dbUtil.getById({
				collection: 'sh-client',
				id: clientIds[i]
			})
			if (!client) {
				throw new Error("接入的设备不存在")
			}
			if (!client.online) {
				throw new Error("接入的设备未上线")
			}
			if (client.roomId) {
				throw new Error("接入的设备正在工作中")
			}
			clientList.push(client)
		}
		//获取当前剧本的阶段列表数据并排序
		let phaseList = await dbUtil.getList({
			collection: 'sh-config-phase',
			where: {
				scriptId: scriptId
			},
			orderByList: [
				["orderNum", "asc"]
			]
		})
		//开始事务
		let transaction = await this.db.startTransaction()
		try {
			let data = {
				dmId: this.ctx.auth.uid,
				dmClientid: dmClientid,
				uids: [],
				clientIds,
				scriptId,
				phaseId: phaseList[0]._id,
				status: 1,
				createTime: Date.now(),
				createBy: this.ctx.auth.uid
			}
			//创建房间
			await dbUtil.insert({
				collection: "sh-gaming-room",
				data,
				transaction
			})
			//修改DM设备状态
			let dmClient = await dbUtil.getOne({
				collection: 'sh-client',
				where: {
					clientId: dmClientid
				}
			})
			if (!dmClient) {
				throw new Error("没有查找到DM")
			}
			await dbUtil.updateById({
				collection: "sh-client",
				data: {
					_id: dmClient._id,
					roomId: data._id
				},
				transaction
			})
			//修改玩家设备状态
			for (let i = 0; i < clientList.length; i++) {
				await dbUtil.updateById({
					collection: "sh-client",
					data: {
						_id: clientList[i]._id,
						roomId: data._id
					},
					transaction
				})
			}
			//创建当前房间剧本的(线索)实时数据
			//查询要创建的线索信息
			let clueList = await dbUtil.getList({
				collection: 'sh-config-clue',
				where: {
					scriptId: data.scriptId
				},
				field: {
					name: true
				}
			})
			//创建每一条线索的实时状态数据
			for (let i = 0; i < clueList.length; i++) {
				await dbUtil.insert({
					collection: "sh-gaming-clue",
					data: {
						roomId: data._id,
						clueConfigId: clueList[i]._id
					},
					transaction
				})
			}
			//创建当前房间剧本的(物品)实时数据
			//查询要创建的物品信息
			let itemList = await dbUtil.getList({
				collection: 'sh-config-item',
				where: {
					scriptId: data.scriptId
				},
				field: {
					name: true
				}
			})
			//创建每一条物品的实时状态数据
			for (let i = 0; i < itemList.length; i++) {
				await dbUtil.insert({
					collection: "sh-gaming-item",
					data: {
						roomId: data._id,
						itemConfigId: itemList[i]._id
					},
					transaction
				})
			}
			//创建当前房间剧本的(人物)实时数据
			//查询要创建的人物信息
			let roleList = await dbUtil.getList({
				collection: 'sh-config-role',
				where: {
					scriptId: data.scriptId
				}
			})
			//创建每一条物品的实时状态数据
			for (let i = 0; i < roleList.length; i++) {
				await dbUtil.insert({
					collection: "sh-gaming-player-state",
					data: {
						roomId: data._id,
						roleId: roleList[i]._id,
						scriptId: roleList[i].scriptId,
						name: roleList[i].name,
						blood: roleList[i].initialBlood,
						magic: roleList[i].initialMagic,
						money: roleList[i].initialMoney,
						counterfeitMoney: roleList[i].initialCounterfeitMoney
					},
					transaction
				})
			}
			//创建当前房间剧本的(人物技能)实时数据
			//查询要创建的人物技能信息
			let skillList = await dbUtil.getList({
				collection: 'sh-config-role-skill',
				where: {
					scriptId: data.scriptId
				},
				field: {
					roleId: true
				}
			})
			//创建每一条人物技能的实时状态数据
			for (let i = 0; i < skillList.length; i++) {
				await dbUtil.insert({
					collection: "sh-gaming-player-skill",
					data: {
						roomId: data._id,
						skillConfigId: skillList[i]._id,
						playerId: skillList[i].roleId,
						useCount: 0
					},
					transaction
				})
			}
			//发送消息给设备
			for (let i = 0; i < clientList.length; i++) {
				await this.pushMessage({
					clientId: clientList[i].clientId,
					type: MSG_START,
					data: {
						roomId: data._id,
						scriptName: script.name
					}
				})
			}
			await transaction.commit()
			return data
		} catch (e) {
			console.error(e)
			await transaction.rollback()
			throw e
		}
	}

	//剧本开始后获取当前剧本的DM信息
	async getDmList({
		roomId
	}) {
		//判断房间是否存在
		let room = await dbUtil.getById({
			collection: 'sh-gaming-room',
			id: roomId
		})
		if (!room) {
			throw new Error("该房间不存在")
		}
		let dbCmd = this.db.command
		let $ = dbCmd.aggregate
		try {
			//获取当前剧本的阶段列表数据并排序
			let phaseList = await dbUtil.getList({
				collection: 'sh-config-phase',
				where: {
					scriptId: room.scriptId
				},
				orderByList: [
					["orderNum", "asc"]
				]
			})
			for (let i = 0; i < phaseList.length; i++) {
				//获取线索配置表
				let clueRes = await this.db.collection('sh-config-clue').aggregate()
					.match({
						phaseId: phaseList[i]._id
					})
					.lookup({
						from: 'sh-config-role',
						let: {
							roleIds: '$roleIds'
						},
						pipeline: $.pipeline()
							.match(dbCmd.expr($.and([
								$.in(['$_id', '$$roleIds'])
							])))
							.project({
								name: 1
							})
							.done(),
						as: 'roles',
					})
					.lookup({
						from: 'sh-gaming-clue',
						let: {
							clueId: '$_id'
						},
						pipeline: $.pipeline()
							.match(dbCmd.expr($.and([
								$.eq(['$clueConfigId', '$$clueId']),
								$.eq(['$roomId', roomId])
							])))
							.project({
								playerIds: 1,
								releasedTime: 1,
								publicTime: 1,
								publicBy: 1
							})
							.done(),
						as: 'gamingClues',
					})
					.end()
				clueRes.data.forEach(item => {
					delete item.roleIds
					item.playerIds = item.gamingClues[0].playerIds
					item.releasedTime = item.gamingClues[0].releasedTime
					item.publicTime = item.gamingClues[0].publicTime
					item.publicBy = item.gamingClues[0].publicBy
					delete item.gamingClues
				})
				phaseList[i].clueList = clueRes.data
				//获取物品配置表
				let itemRes = await this.db.collection('sh-config-item').aggregate()
					.match({
						phaseId: phaseList[i]._id
					})
					.lookup({
						from: 'sh-config-role',
						let: {
							roleIds: '$roleIds'
						},
						pipeline: $.pipeline()
							.match(dbCmd.expr($.and([
								$.in(['$_id', '$$roleIds'])
							])))
							.project({
								name: 1
							})
							.done(),
						as: 'roles',
					})
					.lookup({
						from: 'sh-gaming-item',
						let: {
							itemId: '$_id'
						},
						pipeline: $.pipeline()
							.match(dbCmd.expr($.and([
								$.eq(['$itemConfigId', '$$itemId']),
								$.eq(['$roomId', roomId])
							])))
							.project({
								playerIds: 1,
								releasedTime: 1
							})
							.done(),
						as: 'itemClues',
					})
					.end()
				itemRes.data.forEach(item => {
					delete item.roleIds
					item.playerIds = item.itemClues[0].playerIds
					item.releasedTime = item.itemClues[0].releasedTime
					delete item.itemClues
				})
				let itemList = [],
					contentList = [],
					endingList = []
				itemRes.data.forEach(item => {
					if (item.type == 1) {
						itemList.push(item)
					} else if (item.type == 2) {
						contentList.push(item)
					} else {
						endingList.push(item)
					}
				})
				phaseList[i].itemList = itemList
				phaseList[i].contentList = contentList
				phaseList[i].endingList = endingList
				//剧本开本手册配置表
				// phaseList[i].manual = await dbUtil.getList({
				// 	collection: 'sh-config-manual',
				// 	where: {
				// 		phaseId: phaseList[i]._id
				// 	}
				// })
				//剧本搜证地图配置表
				// phaseList[i].mapList = await dbUtil.getList({
				// 	collection: 'sh-config-map',
				// 	where: {
				// 		phaseId: phaseList[i]._id
				// 	}
				// })
				//剧本问答配置表
				phaseList[i].questionList = await dbUtil.getList({
					collection: 'sh-config-question',
					where: {
						phaseId: phaseList[i]._id
					}
				})
			}
			return phaseList
		} catch (e) {
			console.error(e)
			throw e
		}
	}

	//通过房间id获取DM手册
	async getDmManual({
		roomId
	}) {
		try {
			//判断房间是否存在
			let room = await dbUtil.getById({
				collection: 'sh-gaming-room',
				id: roomId
			})
			if (!room) {
				throw new Error("该房间不存在")
			}
			//获取剧本手册
			let manual = await dbUtil.getById({
				collection: 't3ds-script',
				id: room.scriptId,
				field: {
					manual: true
				}
			})
			return manual
		} catch (e) {
			console.error(e)
			throw e
		}
	}

	//通过房间id获取当前剧本的角色列表
	async getRoleList({
		roomId
	}) {
		let dbCmd = this.db.command
		let $ = dbCmd.aggregate
		try {
			//判断房间是否存在
			let room = await dbUtil.getById({
				collection: 'sh-gaming-room',
				id: roomId
			})
			if (!room) {
				throw new Error("该房间不存在")
			}
			//获取剧本的角色信息
			// let roleList = await dbUtil.getList({
			// 	collection: 'sh-config-role',
			// 	where: {
			// 		scriptId: room.scriptId
			// 	}
			// })
			let roleList = await this.db.collection('sh-gaming-player-state').aggregate()
				.match({
					roomId: roomId
				})
				.lookup({
					from: 'sh-config-role',
					let: {
						roleId: '$roleId'
					},
					pipeline: $.pipeline()
						.match(dbCmd.expr($.and([
							$.eq(['$_id', '$$roleId'])
						])))
						.project({
							avatarSmall: 1,
							avatarLarge: 1,
							introduce: 1,
							gender: 1,
						})
						.done(),
					as: 'roleDetail',
				})
				.end()
			roleList.data.forEach(item => {
				item.avatarSmall = item.roleDetail[0].avatarSmall
				item.avatarLarge = item.roleDetail[0].avatarLarge
				item.introduce = item.roleDetail[0].introduce
				item.gender = item.roleDetail[0].gender
				delete item.roleDetail
			})
			let skillList = await this.db.collection('sh-gaming-player-skill').aggregate()
				.match({
					roomId: roomId,
					
				})
				.lookup({
					from: 'sh-config-role-skill',
					let: {
						skillId: '$skillConfigId'
					},
					pipeline: $.pipeline()
						.match(dbCmd.expr($.and([
							$.eq(['$_id', '$$skillId'])
						])))
						.project({
							name: 1,
							introduce: 1,
							othersCanView: 1,
						})
						.done(),
					as: 'skillDetail',
				})
				.end()
			skillList.data.forEach(item => {
				item.name = item.skillDetail[0].name
				item.introduce = item.skillDetail[0].introduce
				item.othersCanView = item.skillDetail[0].othersCanView
				delete item.skillDetail
			})
			let temp = {}
			temp.roleList = roleList
			temp.skillList = skillList
			return temp
		} catch (e) {
			console.error(e)
			throw e
		}
	}

	//DM给玩家发送线索（游戏中）
	async sendClue({
		roomId,
		clueId,
		playerIds
	}) {
		//判断房间是否存在
		let room = await dbUtil.getById({
			collection: 'sh-gaming-room',
			id: roomId
		})
		if (!room) {
			throw new Error("该房间不存在")
		}
		//判断线索是否存在
		let clue = await dbUtil.getOne({
			collection: 'sh-gaming-clue',
			where: {
				roomId: roomId,
				clueConfigId: clueId
			}
		})
		if (!clue) {
			throw new Error("该线索不存在")
		}
		//判断要发送的玩家是否存在
		let clientIds = []
		for (let i = 0; i < playerIds.length; i++) {
			let player = await dbUtil.getOne({
				collection: 'sh-gaming-player-state',
				where: {
					roomId: roomId,
					roleId: playerIds[i]
				}
			})
			if (!player) {
				throw new Error("发送的角色不存在")
			}
			if(player.clientid) {
				clientIds.push(player.clientid)
			}
		}
		//开始事务
		let transaction = await this.db.startTransaction()
		try {
			let data = {
				_id: clue._id,
				playerIds: playerIds,
				releasedTime: Date.now()
			}
			//判断是否为公开线索，是给公开时间
			let configClue = await dbUtil.getById({
				collection: 'sh-config-clue',
				id: clueId
			})
			if(configClue.public) {
				data.publicTime = Date.now()
			}
			//修改线索的下发时间
			await dbUtil.updateById({
				collection: "sh-gaming-clue",
				data: data,
				transaction
			})
			//在玩家线索表中创建数据
			for (let i = 0; i < playerIds.length; i++) {
				//判断该玩家是否已搜证该线索
				let temp = await dbUtil.getOne({
					collection: 'sh-gaming-player-clue',
					where: {
						roomId: roomId,
						clueId: clue._id,
						playerId: playerIds[i],
					}
				})
				if (!temp) {
					await dbUtil.insert({
						collection: "sh-gaming-player-clue",
						data: {
							roomId: roomId,
							clueConfigId: clueId,
							clueId: clue._id,
							playerId: playerIds[i],
							receiveTime: Date.now()
						},
						transaction
					})
				}
			}
			if(configClue.public) {
				//发送消息给设备(公有线索)
				//获取当前房间设备集合
				let clientList = await dbUtil.getList({
					collection: 'sh-client',
					where: {
						roomId: roomId
					}
				})
				//发送消息给设备
				for (let i = 0; i < clientList.length; i++) {
					await this.pushMessage({
						clientId: clientList[i].clientId,
						type: MSG_SEND_CLUE,
						data: {}
					})
				}
			}else {
				//发送消息给设备(私有线索)
				for (let i = 0; i < clientIds.length; i++) {
					await this.pushMessage({
						clientId: clientIds[i],
						type: MSG_SEND_CLUE,
						data: {
							// default: defaultId,
							// change: player.roleId,
							// uid: this.ctx.auth.uid,
						}
					})
				}
			}
			await transaction.commit()
			return "发送线索成功"
		} catch (e) {
			console.error(e)
			await transaction.rollback()
			throw e
		}
	}

	//DM撤回某一条线索（游戏中）
	async cancelClue({
		roomId,
		clueId
	}) {
		//判断房间是否存在
		let room = await dbUtil.getById({
			collection: 'sh-gaming-room',
			id: roomId
		})
		if (!room) {
			throw new Error("该房间不存在")
		}
		//判断线索是否存在
		let clue = await dbUtil.getOne({
			collection: 'sh-gaming-clue',
			where: {
				roomId: roomId,
				clueConfigId: clueId
			}
		})
		if (!clue) {
			throw new Error("该线索不存在")
		}
		//开始事务
		let transaction = await this.db.startTransaction()
		try {
			//删除线索的下发时间和下发列表
			await dbUtil.updateById({
				collection: "sh-gaming-clue",
				data: {
					_id: clue._id,
					playerIds: [],
					releasedTime: null,
					publicTime:null
				},
				transaction
			})
			//删除玩家线索表中此线索的数据
			let clueList = await dbUtil.getList({
				collection: 'sh-gaming-player-clue',
				where: {
					roomId: roomId,
					clueConfigId: clueId
				}
			})
			for (let i = 0; i < clueList.length; i++) {
				await dbUtil.removeById({
					collection: "sh-gaming-player-clue",
					id: clueList[i]._id,
					transaction
				})
			}
			//获取当前房间设备集合
			let clientList = await dbUtil.getList({
				collection: 'sh-client',
				where: {
					roomId: roomId
				}
			})
			//发送消息给设备
			for (let i = 0; i < clientList.length; i++) {
				await this.pushMessage({
					clientId: clientList[i].clientId,
					type: MSG_CANCEL_CLUE,
					data: {}
				})
			}
			await transaction.commit()
			return "撤回线索成功"
		} catch (e) {
			console.error(e)
			await transaction.rollback()
			throw e
		}
	}

	//DM给玩家发送(道具，内容，结局)（游戏中）
	async sendItem({
		roomId,
		itemId,
		playerIds
	}) {
		//判断房间是否存在
		let room = await dbUtil.getById({
			collection: 'sh-gaming-room',
			id: roomId
		})
		if (!room) {
			throw new Error("该房间不存在")
		}
		//判断物品是否存在
		let item = await dbUtil.getOne({
			collection: 'sh-gaming-item',
			where: {
				roomId: roomId,
				itemConfigId: itemId
			}
		})
		if (!item) {
			throw new Error("该道具不存在")
		}
		let clientIds = []
		//判断要发送的玩家是否存在
		for (let i = 0; i < playerIds.length; i++) {
			let player = await dbUtil.getOne({
				collection: 'sh-gaming-player-state',
				where: {
					roomId: roomId,
					roleId: playerIds[i]
				}
			})
			if (!player) {
				throw new Error("发送的角色不存在")
			}
			if(player.clientid) {
				clientIds.push(player.clientid)
			}
		}
		//开始事务
		let transaction = await this.db.startTransaction()
		try {
			//修改物品的下发时间
			await dbUtil.updateById({
				collection: "sh-gaming-item",
				data: {
					_id: item._id,
					playerIds: playerIds,
					releasedTime: Date.now()
				},
				transaction
			})
			//在玩家物品表中创建数据
			for (let i = 0; i < playerIds.length; i++) {
				await dbUtil.insert({
					collection: "sh-gaming-player-item",
					data: {
						roomId: roomId,
						itemConfigId: itemId,
						itemId: item._id,
						playerId: playerIds[i],
						receiveTime: Date.now()
					},
					transaction
				})
			}
			//发送消息给设备(私有线索)
			for (let i = 0; i < clientIds.length; i++) {
				await this.pushMessage({
					clientId: clientIds[i],
					type: MSG_SEND_ITEM,
					data: {}
				})
			}
			await transaction.commit()
			return "发送物品成功"
		} catch (e) {
			console.error(e)
			await transaction.rollback()
			throw e
		}
	}

	//DM撤回某一个(道具，内容，结局)（游戏中）
	async cancelItem({
		roomId,
		itemId
	}) {
		//判断房间是否存在
		let room = await dbUtil.getById({
			collection: 'sh-gaming-room',
			id: roomId
		})
		if (!room) {
			throw new Error("该房间不存在")
		}
		//判断物品是否存在
		let item = await dbUtil.getOne({
			collection: 'sh-gaming-item',
			where: {
				roomId: roomId,
				itemConfigId: itemId
			}
		})
		if (!item) {
			throw new Error("该道具不存在")
		}
		//开始事务
		let transaction = await this.db.startTransaction()
		try {
			//删除物品的下发时间和下发列表
			await dbUtil.updateById({
				collection: "sh-gaming-item",
				data: {
					_id: item._id,
					playerIds: [],
					releasedTime: null
				},
				transaction
			})
			//删除玩家物品表中此线索的数据
			let itemList = await dbUtil.getList({
				collection: 'sh-gaming-player-item',
				where: {
					roomId: roomId,
					itemConfigId: itemId
				}
			})
			for (let i = 0; i < itemList.length; i++) {
				await dbUtil.removeById({
					collection: "sh-gaming-player-item",
					id: itemList[i]._id,
					transaction
				})
			}
			//发送消息给设备
			//获取当前房间设备集合
			let clientList = await dbUtil.getList({
				collection: 'sh-client',
				where: {
					roomId: roomId
				}
			})
			//发送消息给设备
			for (let i = 0; i < clientList.length; i++) {
				await this.pushMessage({
					clientId: clientList[i].clientId,
					type: MSG_CANCEL_ITEM,
					data: {}
				})
			}
			await transaction.commit()
			return "撤回物品成功"
		} catch (e) {
			console.error(e)
			await transaction.rollback()
			throw e
		}
	}
	
	//修改当前房间的阶段ID
	async updatePhaseId({
		roomId,
		phaseId
	}) {
		//判断房间是否存在
		let room = await dbUtil.getById({
			collection: 'sh-gaming-room',
			id: roomId
		})
		if (!room) {
			throw new Error("该房间不存在")
		}
		//判断该阶段是否存在
		let phase = await dbUtil.getById({
			collection: 'sh-config-phase',
			id: phaseId
		})
		if (!phase) {
			throw new Error("该阶段不存在")
		}
		try {
			//修改当前阶段
			await dbUtil.updateById({
				collection: "sh-gaming-room",
				data: {
					_id: roomId,
					phaseId: phaseId
				}
			})
			//获取当前房间设备集合
			let clientList = await dbUtil.getList({
				collection: 'sh-client',
				where: {
					roomId: roomId
				}
			})
			//发送消息给设备
			for (let i = 0; i < clientList.length; i++) {
				await this.pushMessage({
					clientId: clientList[i].clientId,
					type: MSG_SWITCH_PHASE,
					data: {
						phaseName: phase.name,
						suggestedTime: phase.suggestedTime
						// default: defaultId,
						// change: player.roleId,
						// uid: this.ctx.auth.uid,
					}
				})
			}
			return "修改阶段成功"
		} catch (e) {
			console.error(e)
			throw e
		}
	}
	
	//进入投凶阶段后创建问题（已存在不创建）
	async insertQuestion({
		roomId,
		phaseId
	}) {
		//判断房间是否存在
		let room = await dbUtil.getById({
			collection: 'sh-gaming-room',
			id: roomId
		})
		if (!room) {
			throw new Error("该房间不存在")
		}
		//判断该阶段是否存在
		let phase = await dbUtil.getById({
			collection: 'sh-config-phase',
			id: phaseId
		})
		if (!phase) {
			throw new Error("该阶段不存在")
		}
		//定位到问题ID
		let question = await dbUtil.getOne({
			collection: 'sh-config-question',
			where: {
				phaseId: phaseId
			}
		})
		if (!question) {
			throw new Error("该问题不存在")
		}
		try {
			//判断问题（游戏中）是否存在
			let gamingQuestion = await dbUtil.getOne({
				collection: 'sh-gaming-question',
				where: {
					roomId: roomId,
					questionConfigId: question._id
				}
			})
			if(!gamingQuestion) {
				//创建问题（游戏中）
				await dbUtil.insert({
					collection: "sh-gaming-question",
					data: {
						roomId: roomId,
						questionConfigId: question._id,
						public: false
					}
				})
			}
			//获取当前房间设备集合
			let clientList = await dbUtil.getList({
				collection: 'sh-client',
				where: {
					roomId: roomId
				}
			})
			//发送消息给设备
			for (let i = 0; i < clientList.length; i++) {
				await this.pushMessage({
					clientId: clientList[i].clientId,
					type: MSG_SEND_QUESTION,
					data: {
						question: question
					}
				})
			}
			return question
		} catch (e) {
			console.error(e)
			throw e
		}
	}
	
	//通过房间id和角色id（选择角色）
	async ChooseRole({
		roomId,
		roleId,
		clientid
	}) {
		//判断房间是否存在
		let room = await dbUtil.getById({
			collection: 'sh-gaming-room',
			id: roomId
		})
		if (!room) {
			throw new Error("该房间不存在")
		}
		//判断该角色是否存在
		let player = await dbUtil.getOne({
			collection: 'sh-gaming-player-state',
			where: {
				roomId: roomId,
				roleId: roleId
			}
		})
		if (!player) {
			throw new Error("选择的角色不存在")
		}
		if(player.uid) {
			throw new Error("该角色已被选择")
		}
		//开始事务
		let transaction = await this.db.startTransaction()
		try {
			let defaultId = ''
			//判断该设备是否已绑定其他角色，如绑定解绑
			let chooseRole = await dbUtil.getOne({
				collection: 'sh-gaming-player-state',
				where: {
					roomId: roomId,
					uid: this.ctx.auth.uid
				}
			})
			if(chooseRole && chooseRole.roleId != roleId) {
				defaultId = chooseRole.roleId
				//清除设备的旧角色
				await dbUtil.updateById({
					collection: "sh-gaming-player-state",
					data: {
						_id: chooseRole._id,
						uid: null,
						clientid: null
					},
					transaction
				})
			}
			//修改设备角色
			await dbUtil.updateById({
				collection: "sh-gaming-player-state",
				data: {
					_id: player._id,
					uid: this.ctx.auth.uid,
					clientid: clientid
				},
				transaction
			})
			//获取当前房间设备集合
			let clientList = await dbUtil.getList({
				collection: 'sh-client',
				where: {
					roomId: roomId
				}
			})
			//发送消息给设备
			for (let i = 0; i < clientList.length; i++) {
				await this.pushMessage({
					clientId: clientList[i].clientId,
					type: MSG_SWITCH_ROLES,
					data: {
						default: defaultId,
						change: player.roleId,
						uid: this.ctx.auth.uid,
					}
				})
			}
			await transaction.commit()
			return "选择成功"
		} catch (e) {
			await transaction.rollback()
			console.error(e)
			throw e
		}
	}
	
	//设备选择角色后，获取当前阶段的剧本内容
	async getScriptContent({
		roomId
	}) {
		//判断房间是否存在(拿到阶段ID)
		let room = await dbUtil.getById({
			collection: 'sh-gaming-room',
			id: roomId
		})
		if (!room) {
			throw new Error("该房间不存在")
		}
		//判断本机是否绑定角色（获取角色ID）
		let role = await dbUtil.getOne({
			collection: 'sh-gaming-player-state',
			where: {
				roomId: roomId,
				uid: this.ctx.auth.uid
			}
		})
		if(!role) {
			throw new Error("当前设备没有绑定角色")
		}
		try {
			//获取角色当前阶段的剧本内容
			let scriptDetail = await dbUtil.getOne({
				collection: 'sh-config-role-script',
				where: {
					phaseId: room.phaseId,
					roleId: role.roleId
				}
			})
			return scriptDetail
		} catch (e) {
			console.error(e)
			throw e
		}
	}
	
	//接收到DM发送线索的请求后获取当前角色的所有可查看的线索
	async getRoleClue({
		roomId
	}) {
		//判断房间是否存在
		let room = await dbUtil.getById({
			collection: 'sh-gaming-room',
			id: roomId
		})
		if (!room) {
			throw new Error("该房间不存在")
		}
		//判断本机是否绑定角色（获取角色ID）
		let role = await dbUtil.getOne({
			collection: 'sh-gaming-player-state',
			where: {
				roomId: roomId,
				uid: this.ctx.auth.uid
			}
		})
		if(!role) {
			throw new Error("当前设备没有绑定角色")
		}
		let dbCmd = this.db.command
		let $ = dbCmd.aggregate
		try {
			//获取当前房间本机角色的所有已获得的线索
			// let clueList = await dbUtil.getList({
			// 	collection: 'sh-gaming-player-clue',
			// 	where: {
			// 		roomId: roomId,
			// 		playerId: role.roleId
			// 	}
			// })
			let clueList = {}
			let privateIds = []
			let privateClue = await this.db.collection('sh-gaming-player-clue').aggregate()
				.match({
					roomId: roomId,
					playerId: role.roleId
				})
				.lookup({
					from: 'sh-config-clue',
					let: {
						clueId: '$clueConfigId'
					},
					pipeline: $.pipeline()
						.match(dbCmd.expr($.and([
							$.eq(['$_id', '$$clueId'])
						])))
						.project({
							title: 1,
							subTitle: 1,
							detail: 1,
							canSell: 1,
							image: 1,
							phaseId: 1
						})
						.done(),
					as: 'clueDetail',
				})
				.lookup({
					from: 'sh-gaming-clue',
					let: {
						gamingClueId: '$clueId'
					},
					pipeline: $.pipeline()
						.match(dbCmd.expr($.and([
							$.eq(['$_id', '$$gamingClueId'])
						])))
						.project({
							publicTime: 1,
							publicBy: 1
						})
						.done(),
					as: 'gamingClueDetail',
				})
				.end()
				let phaseIds = []
				privateClue.data.forEach(item => {
					item.phaseId = item.clueDetail[0].phaseId
					phaseIds.push(item.clueDetail[0].phaseId)
					privateIds.push(item.clueId)
					item.title = item.clueDetail[0].title
					item.subTitle = item.clueDetail[0].subTitle
					item.detail = item.clueDetail[0].detail
					item.canSell = item.clueDetail[0].canSell
					item.image = item.clueDetail[0].image
					delete item.clueDetail
					item.publicTime = item.gamingClueDetail[0].publicTime
					item.publicBy = item.gamingClueDetail[0].publicBy
					delete item.gamingClueDetail
				})
				clueList.privateClue = privateClue
				//存在线索的阶段
				let phaseList = await this.db.collection('sh-config-phase').aggregate()
				.match({
					_id: dbCmd.in(phaseIds)
				})
				.sort({
					orderNum: 1
				})
				.end()
				clueList.usePhase = phaseList
				//公有线索
				let publicClue = await this.db.collection('sh-gaming-clue').aggregate()
					.match({
						roomId: roomId,
						publicTime: dbCmd.exists(true) && dbCmd.neq(null),
						_id: dbCmd.nin(privateIds)
					})
					.lookup({
						from: 'sh-config-clue',
						let: {
							clueId: '$clueConfigId'
						},
						pipeline: $.pipeline()
							.match(dbCmd.expr($.and([
								$.eq(['$_id', '$$clueId'])
							])))
							.project({
								title: 1,
								subTitle: 1,
								detail: 1,
								canSell: 1,
								image: 1
							})
							.done(),
						as: 'clueDetail',
					})
					.end()
					publicClue.data.forEach(item => {
						item.title = item.clueDetail[0].title
						item.subTitle = item.clueDetail[0].subTitle
						item.detail = item.clueDetail[0].detail
						item.canSell = item.clueDetail[0].canSell
						item.image = item.clueDetail[0].image
						delete item.clueDetail
					})
					clueList.publicClue = publicClue
			return clueList
		} catch (e) {
			console.error(e)
			throw e
		}
	}
	
	//接收到DM发送线索的请求后获取当前角色的所有已接受的物品（道具，剧本，结局）
	async getRoleItem({
		roomId
	}) {
		//判断房间是否存在
		let room = await dbUtil.getById({
			collection: 'sh-gaming-room',
			id: roomId
		})
		if (!room) {
			throw new Error("该房间不存在")
		}
		//判断本机是否绑定角色（获取角色ID）
		let role = await dbUtil.getOne({
			collection: 'sh-gaming-player-state',
			where: {
				roomId: roomId,
				uid: this.ctx.auth.uid
			}
		})
		if(!role) {
			throw new Error("当前设备没有绑定角色")
		}
		let dbCmd = this.db.command
		let $ = dbCmd.aggregate
		try {
			//获取当前房间本机角色的所有已获得的物品
			let itemList = await this.db.collection('sh-gaming-player-item').aggregate()
				.match({
					roomId: roomId,
					playerId: role.roleId
				})
				.lookup({
					from: 'sh-config-item',
					let: {
						itemId: '$itemConfigId'
					},
					pipeline: $.pipeline()
						.match(dbCmd.expr($.and([
							$.eq(['$_id', '$$itemId'])
						])))
						.project({
							name: 1,
							type: 1,
							description: 1,
							detail: 1,
							image: 1,
							canSell: 1,
						})
						.done(),
					as: 'itemDetail',
				})
				.end()
				itemList.data.forEach(item => {
					item.name = item.itemDetail[0].name
					item.type = item.itemDetail[0].type
					item.description = item.itemDetail[0].description
					item.detail = item.itemDetail[0].detail
					item.image = item.itemDetail[0].image
					item.canSell = item.itemDetail[0].canSell
					delete item.itemDetail
				})
			return itemList
		} catch (e) {
			console.error(e)
			throw e
		}
	}
	
	//公开当前线索
	async cluePublic({
		roomId,
		clueId
	}) {
		//判断房间是否存在
		let room = await dbUtil.getById({
			collection: 'sh-gaming-room',
			id: roomId
		})
		if (!room) {
			throw new Error("该房间不存在")
		}
		//判断线索是否存在
		let clue = await dbUtil.getOne({
			collection: 'sh-gaming-clue',
			where: {
				roomId: roomId,
				clueConfigId: clueId
			}
		})
		if (!clue) {
			throw new Error("该线索不存在")
		}
		//判断本机是否绑定角色（获取角色ID）
		let role = await dbUtil.getOne({
			collection: 'sh-gaming-player-state',
			where: {
				roomId: roomId,
				uid: this.ctx.auth.uid
			}
		})
		if(!role) {
			throw new Error("当前设备没有绑定角色")
		}
		try {
			await dbUtil.updateById({
				collection: "sh-gaming-clue",
				data: {
					_id: clue._id,
					publicTime: Date.now(),
					publicBy: role.roleId
				}
			})
			//获取当前房间设备集合
			let clientList = await dbUtil.getList({
				collection: 'sh-client',
				where: {
					roomId: roomId
				}
			})
			//发送消息给设备
			for (let i = 0; i < clientList.length; i++) {
				await this.pushMessage({
					clientId: clientList[i].clientId,
					type: MSG_SEND_CLUE,
					data: {}
				})
			}
			return "线索已公开"
		} catch (e) {
			console.error(e)
			throw e
		}
	}
	
	//当前设备修改自己的准备状态
	async updateRoleStatus({
		roomId,
		readyToNextPhase
	}) {
		//判断房间是否存在
		let room = await dbUtil.getById({
			collection: 'sh-gaming-room',
			id: roomId
		})
		if (!room) {
			throw new Error("该房间不存在")
		}
		//判断本机是否绑定角色（获取要修改的角色信息）
		let role = await dbUtil.getOne({
			collection: 'sh-gaming-player-state',
			where: {
				roomId: roomId,
				uid: this.ctx.auth.uid
			}
		})
		if(!role) {
			throw new Error("当前设备没有绑定角色")
		}
		try {
			//修改角色的准备状态
			await dbUtil.updateById({
				collection: "sh-gaming-player-state",
				data: {
					_id: role._id,
					readyToNextPhase: readyToNextPhase
				}
			})
			//发送通知到DM和每个玩家（未完成）
			return "修改成功"
		} catch (e) {
			console.error(e)
			throw e
		}
	}
	
	//保存该玩家关于投凶问题的回答
	async saveAnwser({
		roomId,
		questionConfigId,
		anwser
	}) {
		//判断房间是否存在
		let room = await dbUtil.getById({
			collection: 'sh-gaming-room',
			id: roomId
		})
		if (!room) {
			throw new Error("该房间不存在")
		}
		//判断本机是否绑定角色（获取角色ID）
		let role = await dbUtil.getOne({
			collection: 'sh-gaming-player-state',
			where: {
				roomId: roomId,
				uid: this.ctx.auth.uid
			}
		})
		if(!role) {
			throw new Error("当前设备没有绑定角色")
		}
		
		//判断问题是否存在
		let question1 = await dbUtil.getOne({
			collection: 'sh-gaming-question',
			where: {
				roomId: roomId,
				questionConfigId: questionConfigId
			}
		})
		if (!question1) {
			throw new Error("该问题不存在")
		}
		try {
			//该问题答案是否已存在
			let gamingAnwser = await dbUtil.getOne({
				collection: 'sh-gaming-player-anwser',
				where: {
					roomId: roomId,
					playerId: role.roleId,
					questionId: question1._id
				}
			})
			if (!gamingAnwser) {
				//创建问题答案
				await dbUtil.insert({
					collection: "sh-gaming-player-anwser",
					data: {
						roomId: roomId,
						playerId: role.roleId,
						questionConfigId: question1.questionConfigId,
						questionId: question1._id,
						anwser: anwser
					}
				})
			}else {
				await dbUtil.updateById({
					collection: "sh-gaming-player-anwser",
					data: {
						_id: gamingAnwser._id,
						anwser: anwser
					}
				})
			}
			//发送信息给DM的终端设备
			await this.pushMessage({
				clientId: room.dmClientid,
				type: MSG_SEND_ANWSER,
				data: {
					questionId: question1.questionConfigId,
					playerId: role.roleId,
					anwser: anwser
				}
			})
			return "提交成功"
		} catch (e) {
			console.error(e)
			throw e
		}
	}
	
	//玩家呼叫DM(取消呼叫)
	async callDM({
		roomId,
		confirmOrCancel
	}) {
		//判断房间是否存在
		let room = await dbUtil.getById({
			collection: 'sh-gaming-room',
			id: roomId
		})
		if (!room) {
			throw new Error("该房间不存在")
		}
		//判断本机是否绑定角色（获取角色ID）
		let role = await dbUtil.getOne({
			collection: 'sh-gaming-player-state',
			where: {
				roomId: roomId,
				uid: this.ctx.auth.uid
			}
		})
		if(!role) {
			throw new Error("当前设备没有绑定角色")
		}
		try {
			//发送信息给DM的终端设备
			if(confirmOrCancel) {
				//呼叫
				await this.pushMessage({
					clientId: room.dmClientid,
					type: MSG_CALL_DM,
					data: {
						playerId: role.roleId
					}
				})
			}else {
				//取消呼叫
				await this.pushMessage({
					clientId: room.dmClientid,
					type: MSG_CANCEL_CALL,
					data: {
						playerId: role.roleId
					}
				})
			}
			return "呼叫成功"
		} catch (e) {
			console.error(e)
			throw e
		}
	}
	
	//DM接受玩家的呼叫
		async callOK({
			playerId
		}) {
			//获取当前角色的设备终端id
			let player = await dbUtil.getById({
				collection: 'sh-gaming-player-state',
				id: playerId
			})
			if(!player) {
				throw new Error("该角色没有绑定设备")
			}
			try {
				//发送信息给当前角色的终端设备
				await this.pushMessage({
					clientId: player.clientid,
					type: MSG_CALL_OK,
					data: {}
				})
				return "操作成功"
			} catch (e) {
				console.error(e)
				throw e
			}
		}
		
	// //进入搜证阶段获取线索地图发送给玩家
	async searchClue({
		roomId,
		phaseId
	}) {
		//判断房间是否存在
		let room = await dbUtil.getById({
			collection: 'sh-gaming-room',
			id: roomId
		})
		if (!room) {
			throw new Error("该房间不存在")
		}
		//判断该阶段是否存在
		let phase = await dbUtil.getById({
			collection: 'sh-config-phase',
			id: phaseId
		})
		if (!phase) {
			throw new Error("该阶段不存在")
		}
		try {
			//获取地图
			let map = await dbUtil.getOne({
				collection: 'sh-config-map',
				where: {
					phaseId: phaseId
				}
			})
			let tempMap = {}
			let tempMapPlaces = []
			if(map) {
				tempMap = map
				//获取地图上的地点和线索
				let mapPlaces = await dbUtil.getList({
					collection: 'sh-config-map-place',
					where: {
						mapId: map._id
					}
				})
				if(mapPlaces.length > 0) {
					tempMapPlaces = mapPlaces
				}
			}
			//获取当前房间设备集合
			let clientList = await dbUtil.getList({
				collection: 'sh-client',
				where: {
					roomId: roomId
				}
			})
			//发送消息给设备
			for (let i = 0; i < clientList.length; i++) {
				await this.pushMessage({
					clientId: clientList[i].clientId,
					type: MSG_SEND_MAP,
					data: {
						map: tempMap,
						mapPlaces: tempMapPlaces
					}
				})
			}
			return "发送成功"
		} catch (e) {
			console.error(e)
			throw e
		}
	}
	
	//玩家退出房间
	async quitRoom({
		roomId
	}) {
		//判断房间是否存在
		let room = await dbUtil.getById({
			collection: 'sh-gaming-room',
			id: roomId
		})
		if (!room) {
			throw new Error("该房间不存在")
		}
		//判断本机是否绑定角色（获取角色ID,设备终端ID）
		let role = await dbUtil.getOne({
			collection: 'sh-gaming-player-state',
			where: {
				roomId: roomId,
				uid: this.ctx.auth.uid
			}
		})
		if(!role) {
			throw new Error("当前设备没有绑定角色")
		}
		//查询当前设备是否在此房间
		let client = await dbUtil.getOne({
			collection: 'sh-client',
			where: {
				roomId: roomId,
				clientId: role.clientid
			}
		})
		if(!client) {
			throw new Error("当前设备没有在该房间")
		}
		try {
			//退出房间
			await dbUtil.updateById({
				collection: "sh-client",
				data: {
					_id: client._id,
					roomId: null
				}
			})
			//发送信息给DM的终端设备
			await this.pushMessage({
				clientId: room.dmClientid,
				type: MSG_QUIT_ROOM,
				data: {}
			})
			return "退出成功"
		} catch (e) {
			console.error(e)
			throw e
		}
	}
	
	//向DM发出交易申请
	async dealApply({
		roomId,
		type,
		target,
		clueId,
		itemId,
		skillId,
		description
	}) {
		//判断房间是否存在
		let room = await dbUtil.getById({
			collection: 'sh-gaming-room',
			id: roomId
		})
		if (!room) {
			throw new Error("该房间不存在")
		}
		//判断本机是否绑定角色（获取角色ID）
		let role = await dbUtil.getOne({
			collection: 'sh-gaming-player-state',
			where: {
				roomId: roomId,
				uid: this.ctx.auth.uid
			}
		})
		if(!role) {
			throw new Error("当前设备没有绑定角色")
		}
		//判断目标玩家是否存在
		let targetRole = await dbUtil.getOne({
			collection: 'sh-gaming-player-state',
			where: {
				roomId: roomId,
				roleId: target
			}
		})
		if(!targetRole) {
			throw new Error("您所交易的目标不存在")
		}
		try {
			if(type == 1) {
				//赠送道具
				await dbUtil.insert({
					collection: "sh-gaming-apply",
					data: {
						roomId: roomId,
						type: type,
						playerId: role.roleId,
						target: target,
						itemId: itemId,
						description: description,
						status: 0,
					}
				})
			}else if(type == 2) {
				//道具交易
				await dbUtil.insert({
					collection: "sh-gaming-apply",
					data: {
						roomId: roomId,
						type: type,
						playerId: role.roleId,
						target: target,
						itemId: itemId,
						description: description,
						status: 0,
					}
				})
			}else if(type == 3) {
				//线索交易
				await dbUtil.insert({
					collection: "sh-gaming-apply",
					data: {
						roomId: roomId,
						type: type,
						playerId: role.roleId,
						target: target,
						clueId: clueId,
						description: description,
						status: 0,
					}
				})
			}else if(type == 4) {
				//发动技能
			}
			//发送信息给DM的终端设备
			await this.pushMessage({
				clientId: room.dmClientid,
				type: MSG_DEAL_APPLY,
				data: {}
			})
			return "申请成功"
		} catch (e) {
			console.error(e)
			throw e
		}
	}
	
	//DM获取当前房间的所有交易信息
	async getDealList({
		roomId
	}) {
		//判断房间是否存在
		let room = await dbUtil.getById({
			collection: 'sh-gaming-room',
			id: roomId
		})
		if (!room) {
			throw new Error("该房间不存在")
		}
		let dbCmd = this.db.command
		let $ = dbCmd.aggregate
		try {
			//获取交易信息列表（线索信息）
			let dealList = await this.db.collection('sh-gaming-apply').aggregate()
				.match({
					roomId: roomId
				})
				.lookup({
					from: 'sh-config-clue',
					let: {
						clueId: '$clueId'
					},
					pipeline: $.pipeline()
						.match(dbCmd.expr($.and([
							$.eq(['$_id', '$$clueId'])
						])))
						.project({
							title: 1
						})
						.done(),
					as: 'clueDetail',
				})
				.lookup({
					from: 'sh-config-item',
					let: {
						itemId: '$itemId'
					},
					pipeline: $.pipeline()
						.match(dbCmd.expr($.and([
							$.eq(['$_id', '$$itemId'])
						])))
						.project({
							name: 1
						})
						.done(),
					as: 'itemDetail',
				})
				.lookup({
					from: 'sh-config-role',
					let: {
						playerId: '$playerId'
					},
					pipeline: $.pipeline()
						.match(dbCmd.expr($.and([
							$.eq(['$_id', '$$playerId'])
						])))
						.project({
							name: 1,
						})
						.done(),
					as: 'playerDetail',
				})
				.lookup({
					from: 'sh-config-role',
					let: {
						target: '$target'
					},
					pipeline: $.pipeline()
						.match(dbCmd.expr($.and([
							$.eq(['$_id', '$$target'])
						])))
						.project({
							name: 1,
						})
						.done(),
					as: 'targetDetail',
				})
				.end()
			dealList.data.forEach(item => {
				if(item.clueDetail.length > 0) {
					item.clueTitle = item.clueDetail[0].title
					delete item.clueDetail
				}else if(item.itemDetail.length > 0) {
					item.itemName = item.itemDetail[0].name
					delete item.itemDetail
				}
				item.playerName = item.playerDetail[0].name
				delete item.playerDetail
				item.targeName = item.targetDetail[0].name
				delete item.targetDetail
			})
			return dealList
		} catch (e) {
			console.error(e)
			throw e
		}
	}
	
	//DM审核交易申请
	async auditDeal({
		applyId,
		confirmOrCancel
	}) {
		//判断房间是否存在
		let apply = await dbUtil.getById({
			collection: 'sh-gaming-apply',
			id: applyId
		})
		if (!apply) {
			throw new Error("该申请记录不存在")
		}
		let transaction = await this.db.startTransaction()
		try {
			if(confirmOrCancel) {
				//发送人
				let player1 = await dbUtil.getOne({
					collection: 'sh-gaming-player-state',
					where: {
						roomId: apply.roomId,
						roleId: apply.playerId
					}
				})
				//接受人
				let player2 = await dbUtil.getOne({
					collection: 'sh-gaming-player-state',
					where: {
						roomId: apply.roomId,
						roleId: apply.target
					}
				})
				//通过
				if(apply.type == 1) {
					//赠送道具
					//查询要赠送的道具
					let gamingItem = await dbUtil.getOne({
						collection: 'sh-gaming-player-item',
						where: {
							roomId: apply.roomId,
							itemConfigId: apply.itemId,
							playerId: apply.playerId
						}
					})
					//修改审核状态
					await dbUtil.updateById({
						collection: "sh-gaming-apply",
						data: {
							_id: applyId,
							status: 1
						},
						transaction
					})
					//修改道具所有者
					await dbUtil.updateById({
						collection: 'sh-gaming-player-item',
						data: {
							_id: gamingItem._id,
							playerId: apply.target
						},
						transaction
					})
					//创建消息
					await dbUtil.insert({
						collection: "sh-gaming-message",
						data: {
							roomId: apply.roomId,
							senderId: apply.playerId,
							receiverId: apply.target,
							title: '赠送道具',
							readed: false,
							received: true,
							goodsId: apply.itemId,
							price: 0,
							type: 2
						},
						transaction
					})
					await this.pushMessage({
						clientId: player1.clientid,
						type: MSG_CANCEL_ITEM,
						data: {}
					})
					await this.pushMessage({
						clientId: player2.clientid,
						type: MSG_SEND_ITEM,
						data: {}
					})
				}else if(apply.type == 2) {
					//道具交易
				}else if(apply.type == 3) {
					//线索交易
					//修改审核状态
					await dbUtil.updateById({
						collection: "sh-gaming-apply",
						data: {
							_id: applyId,
							status: 1
						},
						transaction
					})
					//创建消息
					let message = {
						roomId: apply.roomId,
						senderId: apply.playerId,
						receiverId: apply.target,
						title: '线索交易',
						readed: false,
						goodsId: apply.clueId,
						price: 0,
						type: 1
					}
					await dbUtil.insert({
						collection: "sh-gaming-message",
						data: message,
						transaction
					})
					//message.senderName = player1.name
					//获取线索信息
					 let clueDetail = await dbUtil.getById({
					 	collection: 'sh-config-clue',
					 	id: apply.clueId
					 })
					//message.goodsName = clueDetail.title
					//发送消息
					await this.pushMessage({
						clientId: player2.clientid,
						type: MSG_DEAL_CLUE,
						data: {
							message: message
						}
					})
				}else if(apply.type == 4) {
					//发动技能
				}
			}else {
				//拒绝
				await dbUtil.updateById({
					collection: "sh-gaming-apply",
					data: {
						_id: applyId,
						status: -1
					},
					transaction
				})
			}
			await transaction.commit()
			return "操作成功"
		} catch (e) {
			await transaction.rollback()
			console.error(e)
			throw e
		}
	}
	
	//玩家搜证发送线索
	async userGetClue({
		roomId,
		clueId
	}) {
		//判断房间是否存在
		let room = await dbUtil.getById({
			collection: 'sh-gaming-room',
			id: roomId
		})
		if (!room) {
			throw new Error("该房间不存在")
		}
		//判断线索是否存在
		let clue = await dbUtil.getOne({
			collection: 'sh-gaming-clue',
			where: {
				roomId: roomId,
				clueConfigId: clueId
			}
		})
		if (!clue) {
			throw new Error("该线索不存在")
		}
		//判断本机是否绑定角色（获取角色ID）
		let role = await dbUtil.getOne({
			collection: 'sh-gaming-player-state',
			where: {
				roomId: roomId,
				uid: this.ctx.auth.uid
			}
		})
		if(!role) {
			throw new Error("当前设备没有绑定角色")
		}
		//开始事务
		let transaction = await this.db.startTransaction()
		try {
			let data = {
				_id: clue._id,
				releasedTime: Date.now()
			}
			//判断是否为公开线索，是给公开时间
			let configClue = await dbUtil.getById({
				collection: 'sh-config-clue',
				id: clueId
			})
			if(configClue.public) {
				data.publicTime = Date.now()
			}
			//修改线索的下发时间
			await dbUtil.updateById({
				collection: "sh-gaming-clue",
				data: data,
				transaction
			})
			
			//在玩家线索表中创建数据
			await dbUtil.insert({
				collection: "sh-gaming-player-clue",
				data: {
					roomId: roomId,
					clueConfigId: clueId,
					clueId: clue._id,
					playerId: role.roleId,
					receiveTime: Date.now()
				},
				transaction
			})
			if(configClue.public) {
				//发送消息给设备(公有线索)
				//获取当前房间设备集合
				let clientList = await dbUtil.getList({
					collection: 'sh-client',
					where: {
						roomId: roomId
					}
				})
				//发送消息给设备
				for (let i = 0; i < clientList.length; i++) {
					await this.pushMessage({
						clientId: clientList[i].clientId,
						type: MSG_SEND_CLUE,
						data: {}
					})
				}
			}else {
				//发送消息给设备(私有线索)
				await this.pushMessage({
					clientId: role.clientid,
					type: MSG_SEND_CLUE,
					data: {
						// default: defaultId,
						// change: player.roleId,
						// uid: this.ctx.auth.uid,
					}
				})
			}
			await transaction.commit()
			return configClue
		} catch (e) {
			console.error(e)
			await transaction.rollback()
			throw e
		}
	}
	
	//DM给玩家发送技能（游戏中）
	async sendSkill({
		roomId,
		skillId
	}) {
		//判断房间是否存在
		let room = await dbUtil.getById({
			collection: 'sh-gaming-room',
			id: roomId
		})
		if (!room) {
			throw new Error("该房间不存在")
		}
		//判断技能是否存在
		let skill = await dbUtil.getOne({
			collection: 'sh-gaming-player-skill',
			where: {
				roomId: roomId,
				skillConfigId: skillId
			}
		})
		if (!skill) {
			throw new Error("该技能不存在")
		}
		let player = await dbUtil.getOne({
			collection: 'sh-gaming-player-state',
			where: {
				roomId: roomId,
				roleId: skill.playerId
			}
		})
		if (!player) {
			throw new Error("该角色不存在")
		}
		try {
			//修改技能的获得时间
			await dbUtil.updateById({
				collection: "sh-gaming-player-skill",
				data: {
					_id: skill._id,
					receiveTime: Date.now()
				}
			})
			//发送信息给设备
			await this.pushMessage({
				clientId: player.clientid,
				type: MSG_SEND_SKILL,
				data: {}
			})
			return "发送技能成功"
		} catch (e) {
			console.error(e)
			throw e
		}
	}
	
	//用户解决交易申请
	async solveDeal({
		clueId,
		itemId,
		money,
		confirmOrCancel
	}) {
		try {
			if(confirmOrCancel) {
				//同意
				if(clueId) {
					//线索交易
					//查询要交易的线索
					// let gamingItem = await dbUtil.getOne({
					// 	collection: 'sh-gaming-player-item',
					// 	where: {
					// 		roomId: apply.roomId,
					// 		itemConfigId: apply.itemId,
					// 		playerId: apply.playerId
					// 	}
					// })
					//修改审核状态
					await dbUtil.updateById({
						collection: "sh-gaming-apply",
						data: {
							_id: applyId,
							status: 1
						},
						transaction
					})
					//修改线索所有者
					await dbUtil.updateById({
						collection: 'sh-gaming-player-item',
						data: {
							_id: gamingItem._id,
							playerId: apply.target
						},
						transaction
					})
					//创建消息
					await dbUtil.insert({
						collection: "sh-gaming-message",
						data: {
							roomId: apply.roomId,
							senderId: apply.playerId,
							receiverId: apply.target,
							title: '线索交易',
							readed: false,
							received: true,
							goodsId: apply.itemId,
							price: 0,
							type: 2
						},
						transaction
					})
					await this.pushMessage({
						clientId: player1.clientid,
						type: MSG_CANCEL_ITEM,
						data: {}
					})
					await this.pushMessage({
						clientId: player2.clientid,
						type: MSG_SEND_ITEM,
						data: {}
					})
				}else if(itemId) {
					//物品交易
				}
			}else {
				//拒绝
				await dbUtil.updateById({
					collection: "sh-gaming-apply",
					data: {
						_id: applyId,
						status: -1
					},
					transaction
				})
			}
			return "操作成功"
		} catch (e) {
			console.error(e)
			throw e
		}
	}
	
}
